// locutor
// (c) 2008-2009, Normen Müller, normen.mueller@gmail.com  
// $Id: GrGEN.scala 2479 2009-10-06 11:17:29Z nmueller $
package locutor.model

import java.io.File

import scaup.Views._
import scaup.io.Process

import locutor.Conf._

case class GrGENWarning(message: String) extends Throwable(message)
case class GrGENError(message: String) extends Throwable(message)

object GrGEN {
  
  def apply(dir: File, name: String): GrGEN = new GrGEN(dir, name) 
  
}

/** Interface to GrGEN
 * 
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.1 */
private [model] class GrGEN(dir: File, name: String) {
  /* Command line to invoke GrGEN.NET */
  val CMD = (GRGEN_HOME / "GrGEN ").p
  
  /* Output directory of GrGEN.NET */
  val dst = dir/name
  dst.mkdirs
  
  /* Preluded MoC graph model */
  val prelude = this.getClass.getResource("moc.gm").getFile.toFile.content
  
  /* Generate model/ action DLL based on rule file (.grg) <code>r</code> */
  def rules(r: File) = ((p: Process) => {
    p.waitFor match {
      case 0 => (dst/("lgsp-"+name+"Model.dll"), dst/("lgsp-"+name+"Actions.dll"))
      case _ => throw GrGENError(p.stderr.mkString)
    }
  })(Process(CMD + (r copyTo dst/(name+".grg")).getOrElse(throw new GrGENError("Could not generate rule file.")).ap, dst))
  
  /* Generate graph model (.gm) based on the list of models <code>ms</code> append to the preluded one */
  def model(ms: List[File]): File = 
    if(!(true /: ms)(_ && _.exists))
      throw GrGENError("Graph models may not be null.")
    else ((new StringBuilder(prelude) /: ms)(_ append _.content append "\n\n")).toString >>> dst/(name+".gm")
  
  /* Generate script (.grs) based on <code>s</code> */
  def script(s: File /*, xgrs: (ct: CT) => String*/): File = {
    val buf = new StringBuilder
    buf append "new graph \""+(dst/("lgsp-"+name+"Model.dll")).ap+"\" "+name+"\n"
    buf append "select actions \""+(dst/("lgsp-"+name+"Actions.dll")).ap+"\""+"\n"
    buf append s.content+"\n"
    
    //buf append xgrs
    
    buf append "save graph affected.grs\n"
    buf append "exit"
    
    buf.toString >>> dst/(name+".grs")
  }  
}
